home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / network / ka9q / ka9q_src.arc / AX25CMD.C < prev    next >
C/C++ Source or Header  |  1988-07-28  |  12KB  |  596 lines

  1. #include <stdio.h>
  2. #include "global.h"
  3. #include "mbuf.h"
  4. #include "ax25.h"
  5. #include "timer.h"
  6. #include "iface.h"
  7. #include "lapb.h"
  8. #include "cmdparse.h"
  9. #include "session.h"
  10. #include "st.h"            /* DG2KK */
  11.  
  12. extern struct tcb;
  13. #define NULLTCB (struct tcb *)0
  14.  
  15. #ifdef FLOW
  16. extern  int ttyflow;        /* DG2KK (output flowcontrol) */
  17. #endif
  18.  
  19. char *ax25states[] = {
  20.     "Disconnected",
  21.     "Conn pending",
  22.     "Disc pending",
  23.     "Connected",
  24.     "Frame Reject",
  25. };
  26.  
  27. int domycall(),dodigipeat(),doaxstat(),dot1(),dot2(),dot3(),domaxframe(),
  28.     doaxwindow(),dopaclen(),don2(),doaxreset(),doconok();    /* DG2KK */
  29.  
  30. static struct cmds axcmds[] = {
  31.     "conok",    doconok,    0, NULLCHAR,    NULLCHAR, /* DG2KK */
  32.     "digipeat",    dodigipeat,    0, NULLCHAR,    NULLCHAR,
  33.     "maxframe",    domaxframe,    0, NULLCHAR,    NULLCHAR,
  34.     "mycall",    domycall,    0, NULLCHAR,    NULLCHAR,
  35.     "paclen",    dopaclen,    0, NULLCHAR,    NULLCHAR,
  36.     "reset",    doaxreset,    2, "ax25 reset <axcb>", NULLCHAR,
  37.     "retry",    don2,        0, NULLCHAR,    NULLCHAR,
  38.     "status",    doaxstat,    0, NULLCHAR,    NULLCHAR,
  39.     "t1",        dot1,        0, NULLCHAR,    NULLCHAR,
  40.     "t2",        dot2,        0, NULLCHAR,    NULLCHAR,
  41.     "t3",        dot3,        0, NULLCHAR,    NULLCHAR,
  42.     "window",    doaxwindow,    0, NULLCHAR,    NULLCHAR,
  43.     NULLCHAR,    NULLFP,        0, "ax25 subcommands: digipeat maxframe mycall paclen reset retry status\n\tt1 t2 t3 window",    NULLCHAR,
  44. };
  45. /* Multiplexer for top-level ax25 command */
  46. doax25(argc,argv)
  47. int argc;
  48. char *argv[];
  49. {
  50.     return subcmd(axcmds,argc,argv);
  51. }
  52.  
  53. static
  54. doaxreset(argc,argv)
  55. int argc;
  56. char *argv[];
  57. {
  58.     struct ax25_cb *axp;
  59.     extern char notval[];
  60.     long htol();
  61.  
  62.     axp = (struct ax25_cb *)htol(argv[1]);
  63.     if(!ax25val(axp)){
  64.         printf(notval);
  65.         return 1;
  66.     }
  67.     reset_ax25(axp);
  68.     return 0;
  69. }
  70.  
  71. /* Display AX.25 link level control blocks */
  72. static
  73. doaxstat(argc,argv)
  74. int argc;
  75. char *argv[];
  76. {
  77.     register int i;
  78.     register struct ax25_cb *axp;
  79.     char tmp[10];
  80.     extern char notval[];
  81.     long htol();
  82.  
  83.     if(argc < 2){
  84.         printf("    &AXB IF   Snd-Q   Rcv-Q   Remote    State\n");
  85.         for(i=0;i<NHASH;i++){
  86.             for(axp = ax25_cb[i];axp != NULLAX25; axp = axp->next){
  87.                 pax25(tmp,&axp->addr.dest);
  88.                 printf("%8lx %-5s%-8d%-8d%-10s%s\n",
  89.                     (long)axp,axp->interface->name,
  90.                     len_q(axp->txq),len_mbuf(axp->rxq),
  91.                     tmp,ax25states[axp->state]);
  92.             }
  93.         }
  94.         return 0;
  95.     }
  96.     axp = (struct ax25_cb *)htol(argv[1]);
  97.     if(!ax25val(axp)){
  98.         printf(notval);
  99.         return 1;
  100.     }
  101.     dumpstat(axp);
  102.     return 0;
  103. }
  104. /* Dump one control block */
  105. static
  106. dumpstat(axp)
  107. register struct ax25_cb *axp;
  108. {
  109.     char tmp[10];
  110.     int i;
  111.  
  112.     if(axp == NULLAX25 || axp->interface == NULLIF)
  113.         return;
  114.     /* DG2KK: changed "&AXB IF..." to " &AXB IF..." (Atari has 5 digit addr. */
  115.     printf(" &AXB IF   Remote   RBW V(S) V(R) Unack P Retry   T1    T2    T3  State\n");
  116.     pax25(tmp,&axp->addr.dest);
  117.     printf("%4x %-5s%-9s",(int)axp,axp->interface->name,tmp);
  118.     putchar(axp->rejsent ? 'R' : ' ');
  119.     putchar(axp->remotebusy ? 'B' : ' ');
  120.     putchar(axp->waitack ? 'W' : ' ');
  121.     printf(" %4d %4d",axp->vs,axp->vr);
  122.     printf(" %02d/%02d %d",axp->unack,axp->maxframe,axp->proto);
  123.     printf(" %02d/%02d",axp->retries,axp->n2);
  124.     if(run_timer(&axp->t1))
  125.         printf(" %02d/%02d",axp->t1.start - axp->t1.count,
  126.          axp->t1.start);
  127.     else
  128.         printf("   /%02d",axp->t1.start);
  129.  
  130.     if(run_timer(&axp->t2))
  131.         printf(" %02d/%02d",axp->t2.start - axp->t2.count,
  132.          axp->t2.start);
  133.     else
  134.         printf("   /%02d",axp->t2.start);
  135.  
  136.     if(run_timer(&axp->t3))
  137.         printf(" %02d/%02d",axp->t3.start - axp->t3.count,
  138.          axp->t3.start);
  139.     else
  140.         printf("   /%02d",axp->t3.start);
  141.  
  142.     printf(" %s\n",ax25states[axp->state]);
  143.     if(axp->addr.ndigis == 0)
  144.         return;
  145.     printf("Digipeaters:");
  146.     for(i=0;i<axp->addr.ndigis;i++){
  147.         pax25(tmp,&axp->addr.digis[i]);
  148.         printf(" %s",tmp);
  149.     }
  150.     printf("\n");
  151. }
  152.  
  153. /* Display or change our AX.25 address */
  154. static
  155. domycall(argc,argv)
  156. int argc;
  157. char *argv[];
  158. {
  159.     char buf[15];
  160.  
  161.     if(argc < 2){
  162.         pax25(buf,&mycall);
  163.         printf("%s\n",buf);
  164.         return 0;
  165.     }
  166.     if(setcall(&mycall,argv[1]) == -1)
  167.         return -1;
  168.     mycall.ssid |= E;
  169.     return 0;
  170. }
  171.  
  172. /* Control AX.25 digipeating */
  173. static
  174. dodigipeat(argc,argv)
  175. int argc;
  176. char *argv[];
  177. {
  178.     extern int digipeat;
  179.  
  180.     if(argc == 1) {
  181.         printf("digipeat %s\n",digipeat ? "on" : "off");
  182.     } else {
  183.         if(strcmp(argv[1],"on") == 0)
  184.             digipeat = 1;
  185.         else
  186.             digipeat = 0;
  187.     }
  188. }
  189.  
  190. /* Set retransmission timer */
  191. static
  192. dot1(argc,argv)
  193. int argc;
  194. char *argv[];
  195. {
  196.     extern int16 t1init;
  197.  
  198.     if(argc == 1) {
  199.         printf("T1 %d\n",t1init);
  200.     } else {
  201.         t1init = atoi(argv[1]);
  202.     }
  203. }
  204.  
  205. /* Set acknowledgement delay timer */
  206. static
  207. dot2(argc,argv)
  208. int argc;
  209. char *argv[];
  210. {
  211.     extern int16 t2init;
  212.  
  213.     if(argc == 1) {
  214.         printf("T2 %d\n",t2init);
  215.     } else {
  216.         t2init = atoi(argv[1]);
  217.     }
  218. }
  219.  
  220. /* Set idle timer */
  221. static
  222. dot3(argc,argv)
  223. int argc;
  224. char *argv[];
  225. {
  226.     extern int16 t3init;
  227.  
  228.     if(argc == 1) {
  229.         printf("T3 %d\n",t3init);
  230.     } else {
  231.         t3init = atoi(argv[1]);
  232.     }
  233. }
  234.  
  235. /* Set retry limit count */
  236. static
  237. don2(argc,argv)
  238. int argc;
  239. char *argv[];
  240. {
  241.     extern int16 n2;
  242.  
  243.     if(argc == 1) {
  244.         printf("Retry %d\n",n2);
  245.     } else {
  246.         n2 = atoi(argv[1]);
  247.     }
  248. }
  249.  
  250. /* Set maximum number of frames that will be allowed in flight */
  251. static
  252. domaxframe(argc,argv)
  253. int argc;
  254. char *argv[];
  255. {
  256.     extern int16 maxframe;
  257.  
  258.     if(argc == 1) {
  259.         printf("Maxframe %d\n",maxframe);
  260.     } else {
  261.         maxframe = atoi(argv[1]);
  262.     }
  263. }
  264.  
  265. /* Set maximum length of I-frame data field */
  266. static
  267. dopaclen(argc,argv)
  268. int argc;
  269. char *argv[];
  270. {
  271.     extern int16 paclen;
  272.  
  273.     if(argc == 1) {
  274.         printf("Paclen %d\n",paclen);
  275.     } else {
  276.         paclen = atoi(argv[1]);
  277.     }
  278. }
  279.  
  280. /* Set high water mark on receive queue that triggers RNR */
  281. static
  282. doaxwindow(argc,argv)
  283. int argc;
  284. char *argv[];
  285. {
  286.     extern int16 axwindow;
  287.  
  288.     if(argc == 1) {
  289.         printf("Axwindow %d\n",axwindow);
  290.     } else {
  291.         axwindow = atoi(argv[1]);
  292.     }
  293. }
  294. /* End of ax25 subcommands */
  295.  
  296. /* Initiate interactive AX.25 connect to remote station */
  297. doconnect(argc,argv)
  298. int argc;
  299. char *argv[];
  300.  {
  301.     void ax_rx(),ax_tx(),ax_state();
  302.     int ax_parse();
  303.     struct ax25_addr dest;
  304.     struct ax25 addr;
  305.     struct ax25_cb *open_ax25();
  306.     struct interface *ifp;
  307.     struct session *s;
  308.     extern int16 axwindow;
  309.     int i;
  310.  
  311.     for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next)
  312.         if(strcmp(argv[1],ifp->name) == 0)
  313.             break;
  314.  
  315.     if(ifp == NULLIF){
  316.         printf("Interface %s unknown\n",argv[1]);
  317.         return 1;
  318.     }
  319.     setcall(&dest,argv[2]);
  320.     /* See if a session already exists */
  321.     for(s = sessions; s < &sessions[nsessions]; s++){
  322.         if(s->type == AX25TNC
  323.          && addreq(&s->cb.ax25_cb->addr.dest,&dest)){
  324. #if ( MAC || AMIGA )
  325.             printf("Session %lu to %s already exists\n",
  326. #else
  327.             printf("Session %u to %s already exists\n",
  328. #endif
  329.                 s - sessions,argv[2]);
  330.             return 1;
  331.         }
  332.     }
  333.     /* Allocate a session descriptor */
  334.     if((s = newsession()) == NULLSESSION){
  335.         printf("Too many sessions\n");
  336.         return 1;
  337.     }
  338.     if((s->name = malloc((unsigned)strlen(argv[2])+1)) != NULLCHAR)
  339.         strcpy(s->name,argv[2]);
  340.     s->type = AX25TNC;
  341.     s->parse = ax_parse;
  342.     current = s;
  343.     ASSIGN(addr.source,mycall);    /* DG2KK: should be changed */
  344.     setcall(&addr.dest,argv[2]);
  345.     for(i=3; i < argc; i++)
  346.         setcall(&addr.digis[i-3],argv[i]);
  347.  
  348.     addr.ndigis = i - 3;
  349.     s->cb.ax25_cb = open_ax25(&addr,axwindow,ax_rx,ax_tx,ax_state,ifp,(char *)s);
  350.     go();
  351.     return 0;
  352. }
  353.  
  354.  
  355. /* Display changes in AX.25 state */
  356. void
  357. ax_state(axp,old,new)
  358. struct ax25_cb *axp;
  359. int old,new;
  360. {
  361.     struct session *s;
  362.     char remote[10];        /* DG2KK */
  363.  
  364.     s = (struct session *)axp->user;
  365.  
  366.     if(current != NULLSESSION && current->type == AX25TNC && current == s){
  367.         printf("%s\n",ax25states[new]);
  368.  
  369.         /* added to enable a 'bell' when state is connected */
  370. /* ---- DG2KK: AX25 logging ---- */
  371.         if(new == CONNECTED) {
  372.             printf("\007");
  373.             pax25(remote,&axp->addr.dest);
  374.             log(NULLTCB,"Connected to %s",remote);
  375.         }
  376.  
  377.         if(new == DISCONNECTED) {
  378.             pax25(remote,&axp->addr.dest);
  379.             log(NULLTCB,"Disconnected from %s",remote);
  380.             cmdmode();
  381.         }
  382. /* ----- */
  383.         fflush(stdout);
  384.     }
  385.     if(new == DISCONNECTED){
  386.         axp->user = NULLCHAR;
  387.         freesession(s);
  388.     }
  389. }
  390. /* Handle typed characters on AX.25 connection */
  391. int
  392. ax_parse(buf,cnt)
  393. char *buf;
  394. int16 cnt;
  395. {
  396.     struct mbuf *bp;
  397.     register char *cp;
  398.     char c;
  399.  
  400.     if(current == NULLSESSION || current->type != AX25TNC)
  401.         return;    /* "can't happen" */
  402.  
  403.     /* If recording is on, record outgoing stuff too */
  404.     if(current->record != NULLFILE)
  405.         fwrite(buf,1,cnt,current->record);
  406.  
  407.     /* Allocate buffer and start it with the PID */
  408.     b